#!/usr/bin/env python
#coding:utf-8
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import detail_route, list_route
from .models import *
from .serializers import *
import os
import commands
import json
import itertools
from demo_app.tools.parse_hosts import Generate_ansible_hosts
from demo_app.tasks import *
from celery.task.control import revoke
from celery.result import AsyncResult
from time import sleep
from tempfile import NamedTemporaryFile


home_dir = os.path.abspath('.') + '/'

class Ansible_HostViewSet(viewsets.ModelViewSet):
	serializer_class = Ansible_HostSerializer
	queryset = Ansible_Host.objects.all()

class Ansible_Yml_RegisterViewSet(viewsets.ModelViewSet):
	serializer_class = Ansible_Yml_RegisterSerializer
	queryset = Ansible_Yml_Register.objects.all()
	
class DemoViewSet(viewsets.ModelViewSet):
	serializer_class = DemoSerializer
	queryset = Demo.objects.all()

	@list_route(methods=['get', 'post'])
	def touch(self, request):
		os.system('touch /tmp/abc')
		return Response({'msg': '/tmp/abc has been touched'})

	@list_route(methods=['get', 'post'])
	def touch2(self,request):
		os.system('ansible localhost -a "touch /tmp/bcf"')
		return Response({'msg': '/tmp/bcf has been touched'})

	@list_route(methods=['get', 'post'])
	def touch3(self,request):
		bits = 'ansible localhost -a "touch /tmp1/eee"'
		(status,output)=commands.getstatusoutput(bits)
		if status !=0:
			return Response({'msg': '/tmp1/eee has been not touched','output':output})
		return Response({'msg': '/tmp1/eee has been touched','output':output})

	@list_route(methods=['get', 'post'])
	def touch4(self,request):
		bits = 'ansible localhost -a "touch /tmp1/eee"|tee -a /tmp/ansible.log'
		(status,output)=commands.getstatusoutput(bits)
		if status !=0:
			return Response({'msg': '/tmp1/eee has been not touched','output':output})
		return Response({'msg': '/tmp1/eee has been touched','output':output})

	@list_route(methods=['get', 'post'])
	def touch5(self,request):
		bits = 'set -o pipefail;ansible localhost -a "touch /tmp1/eee"|tee -a /tmp/ansible.log'
		(status,output)=commands.getstatusoutput(bits)
		if status !=0:
			return Response({'msg': '/tmp1/eee has been not touched','output':output})
		return Response({'msg': '/tmp1/eee has been touched','output':output})

	@list_route(methods=['get', 'post'])
	def touch6(self,request):
		data = request.data
		filename = data['filename'] 
		bits = 'set -o pipefail;ansible localhost -a "touch {0}"|tee -a /tmp/ansible.log'.format(filename)
		(status,output)=commands.getstatusoutput('bash -c "{0}"'.format(bits))
		if status !=0:
			return Response({'msg': '{0} has been not touched'.format(filename),'output':output})
		return Response({'msg': '{0} has been touched'.format(filename),'output':output})

	@list_route(methods=['get', 'post'])
	def touch7(self,request):
		ansible_playbook = home_dir + '../ansible_file/touch_7.yml'
		bits = 'set -o pipefail;ansible-playbook {0}|tee -a /tmp/ansible.log'.format(ansible_playbook)
		(status,output)=commands.getstatusoutput('bash -c "{0}"'.format(bits))
		if status !=0:
			return Response({'msg': '{0} has been not touched'.format('ggg'),'output':output})
		return Response({'msg': '{0} has been touched'.format('ggg'),'output':output})

	@list_route(methods=['get', 'post'])
	def touch8(self,request):
		data = str(request.data).replace("u'",'\\"').replace("'",'\\"')
		ansible_playbook = home_dir + '../ansible_file/touch_8.yml'
		bits = 'ansible-playbook {0} -e'.format(ansible_playbook) + "'{0}'".format(data)+'|tee -a /tmp/ansible.log'
		comm = 'bash -c "'+'set -o pipefail;{0}"'.format(bits)
		(status,output)=commands.getstatusoutput(comm)
		if status !=0:
			return Response({'msg': '{0} has been not touched'.format('ggg'),'output':output})
		return Response({'msg': '{0} has been touched'.format('ggg'),'output':output})

	def generate_hosts(self):
		data = Ansible_Host.objects.all().values()
		s_data = [{'group': group, 'items': list(items)} for group, items in itertools.groupby(data, lambda x: x['group'])]
		generate_hosts = Generate_ansible_hosts('/tmp/hosts')

		try:
			generate_hosts.create_all_servers(s_data)
			msg = 'hosts has been create'
			flag = True
		except:
			msg = 'hosts has not been create'
			flag = False
		return msg,flag

	@list_route(methods=['get', 'post'])
	def create_ansible_hosts(self, request):
		msg,flag = self.generate_hosts()
		return Response({'msg':msg,'flag':flag})

	@list_route(methods=['get', 'post'])
	def create_ansible_hosts_add(self, request):
		data = request.data
		print data
		#Ansible_Host.objects.create(**data).save()
		msg, flag = self.generate_hosts()
		return Response({'msg': msg, 'flag': flag})

	@list_route(methods=['get', 'post'])
	def create_ansible_hosts_delete(self, request):
		data = request.data
		Ansible_Host.objects.filter(id=data['remove_id']).delete()
		msg, flag = self.generate_hosts()
		return Response({'msg': msg, 'flag': flag})

	@list_route(methods=['get', 'post'])
	def create_ansible_hosts_modify(self, request):
		data = request.data
		print data
		Ansible_Host.objects.filter(id=data['id']).update(**data)
		msg, flag = self.generate_hosts()
		return Response({'msg': msg, 'flag': flag})



	@list_route(methods=['get', 'post'])
	def long_ansible_background_cmd(self, request):
		data = request.data
		s1 = long_ansible_bg.s(data)
		res = s1.delay()
		return Response({'task_id': res.task_id})

	@list_route(methods=['get', 'post'])
	def long_ansible_revoke(self, request):
		data = request.data
		task_id = data['task_id']
		res = AsyncResult(task_id)
		revoke(task_id, terminate=True, signal='SIGKILL')
		return Response({'msg': task_id + ' has been revoked'})

	def check_task_end(self,task_id):
		res = AsyncResult(task_id)
		return res.state


	@list_route(methods=['get', 'post'])
	def read_long_ansible(self,request):
		data = request.data
		
		if not data.has_key('log_file'):
			log_file = '/tmp/long.log'
		else:
			log_file = data['log_file']
		if not os.path.exists(log_file):
			data['read_flag'] = True
			data['logs'] = ''
			return Response(data)
		with open(log_file,'r') as f:
			print log_file
			f.seek(data['seek'])
			data['logs']=f.read()
			data['seek']=f.tell()
		data['state']=self.check_task_end(data['task_id'])
		if data['state'] in ['SUCCESS', 'FAILURE', 'REVOKED']:
			data['read_flag'] = False
		else:
			data['read_flag'] = True
		return Response(data)

	@list_route(methods=['get', 'post'])
	def execute_long_ansible(self, request):
		data = request.data
		f = NamedTemporaryFile(delete=False)
		data['log_file'] = f.name
		res = long_ansible_read_log.delay(data)
		return Response({'task_id': res.task_id, 'log_file': f.name})

	@list_route(methods=['get', 'post'])
	def file_upload(self,request):
		all_str = request.data['para']
		all_data = json.loads(all_str)
		saved_file_name = all_data['saved_file_name']
		saved_file_dir = os.path.dirname(saved_file_name)
		filename = request.data['file']
		file_name = str(filename)
		if not os.path.exists(saved_file_dir):
			os.makedirs(saved_file_dir)
		try:
			destination = open(saved_file_name, 'wb+')
			for chunk in filename.chunks():
				destination.write(chunk)
			destination.close()
			return Response({'flag': True})
		except:
			return Response({'flag': False})


	@list_route(methods=['get', 'post'])
	def create_yml_file(self,request):
		data = request.data
		Ansible_Yml_Register.objects.create(**data)
		return Response({'flag': True})

	@list_route(methods=['get', 'post'])
	def delete_yml_file(self,request):
		data = request.data

		Ansible_Yml_Register.objects.filter(id=data['remove_id']).delete()
		return Response({'flag': True})

	@list_route(methods=['get', 'post'])
	def update_yml_file(self,request):
		data = request.data
		Ansible_Yml_Register.objects.filter(id=data['id']).update(**data)
		return Response({'flag': True})

	
	@list_route(methods=['get', 'post'])
	def execute_yml_ansible(self,request):
		data = request.data

		f = NamedTemporaryFile(delete=False)
		data['log_file'] = f.name
		res = common_ansible_bg.delay(data)
		print data
		return Response({'task_id': res.task_id, 'log_file': f.name})
	







